package com.dd.cloud.user.service.phar.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.auth.entity.AdminRole;
import com.dd.cloud.auth.req.role.UserBindRoleReq;
import com.dd.cloud.auth.res.UserToRoleRes;
import com.dd.cloud.common.config.servlet.JwtUtils;
import com.dd.cloud.common.config.sms.SmsComponent;
import com.dd.cloud.common.constants.AdminConstants;
import com.dd.cloud.common.constants.MechanConstants;
import com.dd.cloud.common.constants.PharConstants;
import com.dd.cloud.common.constants.PresConstants;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.*;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.user.entity.phar.*;
import com.dd.cloud.user.enums.ExceptionEnum;
import com.dd.cloud.user.feign.AuthFeignService;
import com.dd.cloud.user.mapper.phar.PharmacyChooseMapper;
import com.dd.cloud.user.mapper.phar.PharmacyUserMapper;
import com.dd.cloud.user.req.phar.*;
import com.dd.cloud.user.res.admin.AdminUserDetailRes;
import com.dd.cloud.user.res.phar.*;
import com.dd.cloud.user.service.common.ICommonService;
import com.dd.cloud.user.service.phar.*;
import com.dd.cloud.user.service.role.IAdminPowerService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Lx
 * @version 1.0
 */
@Slf4j
@Service
public class PharmacyUserServiceImpl extends ServiceImpl<PharmacyUserMapper, PharmacyUser> implements IPharmacyUserService {

    @Autowired
    private IAdminPowerService adminPowerService;
    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private SmsComponent smsComponent;

    @Autowired
    private ICommonService commonService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private IPharFryingRuleService pharFryingRuleService;

    @Autowired
    private IPharExpressRuleService pharExpressRuleService;

    @Autowired
    private IPharSetFeeRecordService pharSetFeeRecordService;
    @Autowired
    private AuthFeignService authFeignService;

    @Autowired
    private IPharFryingOneRuleService pharFryingOneRuleService;

    @Autowired
    private IPharFryingTwoRuleService pharFryingTwoRuleService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final String PHAR_FRYING_REMARK = "phar_frying_remark:";

    @Autowired
    private PharmacyChooseMapper pharmacyChooseMapper;


    /**
     * @param req:
     * @return Page<StroeUserPageRes>
     * @description 分页查询管理员
     * @author czg
     * @date 2023/2/22 9:59
     */
    @Override
    public Page<StroeUserPageRes> getStoreUserPage(StoreUserPageReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Page<StroeUserPageRes> page = req.pagePojo();
        if (StringUtils.isNotBlank(req.getStatus())) {
            String[] statusStr = req.getStatus().split(",");
            req.setStatusStr(statusStr);
        }
        if (LoginInfo.UserType.PHAR == loginInfo.getType()) {
            req.setPharId(loginInfo.getPharId());
        }
        page = getBaseMapper().getStoreUserPage(page, req);
        List<StroeUserPageRes> records = page.getRecords();
        List<UserToRoleRes> body = authFeignService.userRoleList().getBody();
        for (StroeUserPageRes res : records) {
            for (UserToRoleRes ures : body) {
                if (res.getId().equals(ures.getUserId())) {
                    res.setAdmin(ures.getAdmin());
                    res.setRoleName(ures.getRoleName());
                    continue;
                }
            }
        }
        page.setRecords(records);
        return page;
    }

    @Autowired
    private IPharmacyService pharmacyService;

    @Override
    public void addStoreUser(StoreUserAddReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Pharmacy store = pharmacyService.getById(loginInfo.getPharId());
        if (store == null || store.getStatus() == PharConstants.PharStatus.DEL) {
            throw new ZekeException(ZkExceptionEnum.PARAMETER_ERROR, "药房不存在");
        }
        if (store.getStatus() == PharConstants.PharStatus.DISABLE) {
            throw new ZekeException(400, "药房已禁用");
        }

        QueryWrapper<PharmacyUser> qw = new QueryWrapper<>();
        qw.lambda().ne(PharmacyUser::getStatus, MechanConstants.MechanUserStatus.DEL)
                .and(w -> w.eq(PharmacyUser::getPhone, req.getPhone()));
        int count = count(qw);
        if (count > 0) {
            throw new ZekeException("账号已存在,请重新输入");
        }
        if (!req.getPassword().equals(req.getResPwd())) {
            throw new ZekeException("密码不一致");
        }
        PharmacyUser storeUser = new PharmacyUser();
        BeanUtils.copyProperties(req, storeUser);
        storeUser.setStatus(MechanConstants.MechanUserStatus.NORMAL);
        storeUser.setCreateDate(LocalDateTime.now());
        storeUser.setCreateId(loginInfo.getId());
        storeUser.setCreateName(loginInfo.getName());
        storeUser.setPharId(loginInfo.getPharId());
        // 对密码进行加密
        String salt = CodecUtils.generateSalt();
        storeUser.setSalt(salt);
        String password = req.getPassword();
        if (StringUtils.isBlank(password)) {
            password = storeUser.getPhone().substring(storeUser.getPhone().length() - 6);
        }
        storeUser.setPassword(CodecUtils.md5Hex(password, storeUser.getSalt()));
        boolean i = save(storeUser);
        if (!i) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }
        ResponseEntity<Integer> integerResponseEntity = authFeignService.userIsAdmin(storeUser.getId(), LoginInfo.UserType.PHAR);

        if (integerResponseEntity.getBody() == AdminConstants.Admin.ADMIN) {
            throw new ZekeException("不能添加超级管理员");
        }
        if (req.getRoleId() != null) {
//            adminPowerService.bindUserRole(storeUser.getId(), req.getRoleId(), LoginInfo.UserType.PHAR);
            authFeignService.userBindRole(new UserBindRoleReq(storeUser.getId(), req.getRoleId(), LoginInfo.UserType.PHAR, null));

        }
    }

    @Override
    public AdminUserDetailRes getAdminUserDetail(Integer id) {
        AdminUserDetailRes res = getBaseMapper().getUserDeatil(id);
        if (res == null) {
            return res;
        }
        String password = res.getPassword();

        ResponseEntity<AdminRole> entity = authFeignService.queryRoleByUserId(id, LoginInfo.UserType.PHAR);
        if (entity.getStatusCodeValue() == 200 && entity.getBody() != null) {
            AdminRole adminRole = entity.getBody();
            res.setType(adminRole.getAdmin());
            res.setRoleId(adminRole.getId());
            res.setRoleName(adminRole.getRoleName());
        }
        return res;
    }

    /**
     * @param id:     管理员id
     * @param status: 状态值
     * @return void
     * @description 修改管理员状态
     * @author czg
     * @date 2023/2/22 9:59
     */
    @Override
    public void updateStoreUserStatus(Integer id, Integer status) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.PHAR).get();

        PharmacyUser storeUser = getById(id);
        if (storeUser == null) {
            throw new ZekeException(ZkExceptionEnum.ACCOUNT_NOT_FOUND);
        }

        if (loginInfo.getId().equals(id)) {
            throw new ZekeException(400, "不能操作自己的账号");
        }
        if (storeUser.getStatus().equals(status)) {
            return;
        }
        if (!ObjectUtils.refrect(MechanConstants.MechanUserStatus.class, status)) {
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        storeUser.setStatus(status);
        boolean i = updateById(storeUser);
        if (!i) {
            throw new ZekeException(ZkExceptionEnum.UPDATE_ERROR);
        }
    }

    @Override
    public void updateStoreUser(StoreUserUpdateReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.PHAR).get();
        PharmacyUser storeUser = getById(req.getId());
        if (storeUser == null) {
            throw new ZekeException(ZkExceptionEnum.ACCOUNT_NOT_FOUND);
        }
        QueryWrapper<PharmacyUser> qw = new QueryWrapper<>();
        qw.lambda().ne(PharmacyUser::getStatus, MechanConstants.MechanUserStatus.DEL)
                .ne(PharmacyUser::getPhone, storeUser.getPhone())
                .and(w -> w.eq(PharmacyUser::getPhone, req.getPhone()));
        int count = count(qw);
        if (count > 0) {
            throw new ZekeException(ZkExceptionEnum.PHONE_IS_EXISTS);
        }
        if (StringUtils.isNotBlank(req.getPassword()) && StringUtils.isNotBlank(req.getResPwd())) {
            if (!req.getPassword().equals(req.getResPwd())) {
                throw new ZekeException("密码不一致");
            }
        }
        if (!StringUtils.isBlank(req.getPassword())) {
            storeUser.setPassword(CodecUtils.md5Hex(req.getPassword(), storeUser.getSalt()));
        }
        if (!StringUtils.isBlank(req.getNickName())) {
            storeUser.setNickName(req.getNickName());
        }
        if (!StringUtils.isBlank(req.getPhone())) {
            storeUser.setPhone(req.getPhone());
        }
        storeUser.setEmail(req.getEmail());
//        int powerLogin = adminPowerService.queryRoleIsAdmin(loginInfo.getId(), loginInfo.getType());
//        int powerUpdate = adminPowerService.queryRoleIsAdmin(req.getId(), loginInfo.getType());
//        if (powerLogin != AdminConstants.Admin.ADMIN) {
//            throw new ZekeException(400, "您的账号是普通管理员, 不能修改其他管理员的角色");
//        }
        ResponseEntity<Integer> integerResponseEntity = authFeignService.userIsAdmin(loginInfo.getId(), loginInfo.getType());
        ResponseEntity<Integer> integerResponseEntity2 = authFeignService.userIsAdmin(req.getId(), loginInfo.getType());
        int powerLogin = integerResponseEntity.getBody();
        int powerUpdate = integerResponseEntity2.getBody();
        if (powerUpdate != req.getRoleId() && powerLogin != AdminConstants.Admin.ADMIN) {
            throw new ZekeException(400, "您的账号是普通管理员, 不能修改其他管理员的角色");
        }
        if (powerUpdate == AdminConstants.Admin.ADMIN) {
            throw new ZekeException(400, "不能修改超级管理员");
        }
        boolean updateById = updateById(storeUser);
        if (!updateById) {
            throw new ZekeException(ZkExceptionEnum.UPDATE_ERROR);
        }
        if (req.getRoleId() != null) {
//            adminPowerService.bindUserRole(storeUser.getId(), req.getRoleId(), LoginInfo.UserType.PHAR);
            authFeignService.userBindRole(new UserBindRoleReq(req.getRoleId(), req.getRoleId(), LoginInfo.UserType.ADMIN, null));

        }
    }

    @Override
    public StoreUserLoginRes storeUserLoginPwd(HttpServletRequest request, HttpServletResponse response, String account, String password) {
        //检查密码错误是否超过次数
        commonService.checkLoginPwdError(request, account);
        //查询账号
        QueryWrapper<PharmacyUser> q = new QueryWrapper<>();
        q.lambda().eq(PharmacyUser::getPhone, account);
        q.lambda().ne(PharmacyUser::getStatus, PharConstants.StoreUserStatus.DEL);
        PharmacyUser user = getOne(q);
        if (user == null) {
            throw new ZekeException(ZkExceptionEnum.INVALID_USERNAME_PASSWORD);
        }

        //校验账号状态
        switch (user.getStatus()) {
            case PharConstants.StoreUserStatus.DEL:
                throw new ZekeException(ZkExceptionEnum.ACCOUNT_IS_DELETED);
            case PharConstants.StoreUserStatus.DISABLE:
            case PharConstants.StoreUserStatus.DISABLEADMIN:
                throw new ZekeException(ExceptionEnum.ACCOUNT_IS_NOT_USE);
            default:
        }
        QueryWrapper<Pharmacy> qw = new QueryWrapper<>();
        qw.lambda().eq(Pharmacy::getId, user.getPharId());
        Pharmacy ps = pharmacyService.getOne(qw);
        if (ps == null) {
            throw new ZekeException(ExceptionEnum.ACCOUNT_IS_NOT_PHAR);
        }
        switch (ps.getStatus()) {
            case PharConstants.PharStatus.DEL:
                throw new ZekeException(ExceptionEnum.PHAR_IS_DEL);
            case PharConstants.PharStatus.DISABLE:
                throw new ZekeException(ExceptionEnum.PHAR_IS_DISABLE);
            default:
        }
        //校验密码
        log.info("密码校验=========" + CodecUtils.md5Hex(password, user.getSalt()));
        q.lambda().eq(PharmacyUser::getPassword, CodecUtils.md5Hex(password, user.getSalt()));
        user = getOne(q);
        if (user == null) {
            //增加密码错误次数
            commonService.loginPwdError(request, account);
            throw new ZekeException(ZkExceptionEnum.INVALID_USERNAME_PASSWORD);
        }
        LoginInfo loginInfo = new LoginInfo(user.getId(), LoginInfo.UserType.PHAR, user.getNickName(), user.getPharId(), 0, jwtUtils.getUserAgent(request));
        Integer admin = 2;
        try {
            ResponseEntity<AdminRole> entity = authFeignService.roleIdByUserId(loginInfo);
            loginInfo.setRoleId(entity.getBody().getId());
            admin = entity.getBody().getAdmin();
        } catch (Exception e) {
            log.error("授权失败");
            e.printStackTrace();
        }
        //生成token并写入cookie
        jwtUtils.createToken(loginInfo, request, response);
        StoreUserLoginRes res = new StoreUserLoginRes();
        BeanUtils.copyProperties(user, res);
        //查询用用户的角色
        //Integer type = adminPowerService.queryRoleIsAdmin(user.getId(), LoginInfo.UserType.PHAR);
        res.setType(admin);
        res.setPharName(ps.getName());
        res.setPharFlag(ps.getFlag());
        return res;
    }


    @Override
    public StoreUserLoginRes pharmacyUserLoginCode(HttpServletRequest request,
                                                   HttpServletResponse response,
                                                   String phone,
                                                   String code) {
        if (StringUtils.isBlank(code)) {
            throw new ZekeException(ZkExceptionEnum.INVALID_VERIFY_CODE);
        }

        //查询账号
        QueryWrapper<PharmacyUser> q = new QueryWrapper<>();
        q.lambda().eq(PharmacyUser::getPhone, phone);
        q.lambda().ne(PharmacyUser::getStatus, AdminConstants.UserStatus.DEL);
        PharmacyUser user = getOne(q);
        if (user == null) {
            throw new ZekeException(ZkExceptionEnum.ACCOUNT_NOT_FOUND);
        }
        //校验账号状态
        switch (user.getStatus()) {
            case PharConstants.StoreUserStatus.DEL:
                throw new ZekeException(ZkExceptionEnum.ACCOUNT_IS_DELETED);
            case AdminConstants.UserStatus.DISABLEADMIN:
            case PharConstants.StoreUserStatus.DISABLE:
                throw new ZekeException(ZkExceptionEnum.ACCOUNT_IS_FORBIDDEN);
            default:
        }
        //校验手机验证码
        smsComponent.verifyPhoneCode(phone, code);
        QueryWrapper<Pharmacy> qw = new QueryWrapper<>();
        qw.lambda().eq(Pharmacy::getId, user.getPharId());
        Pharmacy ps = pharmacyService.getOne(qw);
        if (ps == null) {
            throw new ZekeException(ExceptionEnum.ACCOUNT_IS_NOT_PHAR);
        }
        switch (ps.getStatus()) {
            case PharConstants.PharStatus.DEL:
                throw new ZekeException(ExceptionEnum.PHAR_IS_DEL);
            case PharConstants.PharStatus.DISABLE:
                throw new ZekeException(ExceptionEnum.PHAR_IS_DISABLE);
            default:
        }
        LoginInfo loginInfo = new LoginInfo(user.getId(), LoginInfo.UserType.PHAR, user.getNickName(), user.getPharId(), 0, jwtUtils.getUserAgent(request));
        Integer admin = 2;
        try {
            ResponseEntity<AdminRole> entity = authFeignService.roleIdByUserId(loginInfo);
            loginInfo.setRoleId(entity.getBody().getId());
            admin = entity.getBody().getAdmin();
        } catch (Exception e) {
            log.error("授权失败");
            e.printStackTrace();
        }
        jwtUtils.createToken(loginInfo, request, response);
        StoreUserLoginRes res = new StoreUserLoginRes();
        BeanUtils.copyProperties(user, res);
        //查询用用户的角色
        //Integer type = adminPowerService.queryRoleIsAdmin(user.getId(), LoginInfo.UserType.PHAR);
        res.setType(admin);
        res.setPharName(ps.getName());
        return res;
    }

    @Override
    public void updateStoreUserPwd(String oldPwd, String newPwd1, String newPwd2) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.PHAR).get();

        PharmacyUser mu = getById(loginInfo.getId());
        oldPwd = CodecUtils.md5Hex(oldPwd, mu.getSalt());
        if (!Objects.equals(oldPwd, mu.getPassword())) {
            throw new ZekeException(400, "原密码错误");
        }
        mu.setSalt(CodecUtils.generateSalt());
        mu.setPassword(CodecUtils.md5Hex(newPwd2, mu.getSalt()));
        updateById(mu);
    }

    @Override
    public void loginOut(HttpServletRequest request, HttpServletResponse response) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.PHAR).get();
        String token = CookieUtils.getCookieValue(request, jwtUtils.getCookieName(request));
        String type = request.getHeader("client");
        String loginKey = type + loginInfo.getType() + "-" + loginInfo.getId() + "-" + loginInfo.getType();
        if (StringUtils.isNotBlank(token)) {
            log.info("删除token========================================================" + token);
            redisTemplate.delete(loginKey);
            CookieUtils.set(response, jwtUtils.getCookieName(request), null, 0);
        }
    }

    @Override
    public PharExpressRule getPharmacyExpFee() {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.PHAR).get();
        LambdaQueryWrapper<PharExpressRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PharExpressRule::getPharId, loginInfo.getPharId());
        PharExpressRule pharExpressRule = pharExpressRuleService.getOne(wrapper);
        if (ObjectUtil.isNull(pharExpressRule)) {
            PharExpressRule defaultExpressRule = new PharExpressRule();
            defaultExpressRule.setFee(0)
                    .setCityOutFee(0)
                    .setCity("深圳市")
                    .setProvince("广东省")
                    .setProvincialOutFee(0)
                    .setCityFee(0)
                    .setIsChecked(0)
                    .setDeliverWay(1)
                    .setIsOutProvincialChecked(0)
                    .setIsInnerProvincialChecked(0)
                    .setIsInnerCityChecked(0);
            return defaultExpressRule;
        }
        return pharExpressRule;
    }

    @Override
    public PharmacyProcessTypeRes getPharmacyFryFee() {
        PharmacyProcessTypeRes pharmacyProcessTypeRes = new PharmacyProcessTypeRes();
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.PHAR).get();
        LambdaQueryWrapper<PharFryingOneRule> oneWrapper = new LambdaQueryWrapper<>();
        oneWrapper.eq(PharFryingOneRule::getPharId, loginInfo.getPharId())
                .eq(PharFryingOneRule::getStatus, 1);
        List<PharFryingOneRule> pharFryingOneRules = pharFryingOneRuleService.getBaseMapper().selectList(oneWrapper);
        pharmacyProcessTypeRes.setPharFryingOneRules(pharFryingOneRules);
        LambdaQueryWrapper<PharFryingTwoRule> twoWrapper = new LambdaQueryWrapper<>();
        twoWrapper.eq(PharFryingTwoRule::getPharId, loginInfo.getPharId())
                .eq(PharFryingTwoRule::getStatus, 1);
        List<PharFryingTwoRule> pharFryingTwoRules = pharFryingTwoRuleService.getBaseMapper().selectList(twoWrapper);
        pharmacyProcessTypeRes.setPharFryingTwoRules(pharFryingTwoRules);
        pharmacyProcessTypeRes = getAllProcessType(pharmacyProcessTypeRes);
        String remark = redisTemplate.opsForValue().get(PHAR_FRYING_REMARK + loginInfo.getPharId());
        pharmacyProcessTypeRes.setRemark(remark);
        return pharmacyProcessTypeRes;
    }


    public PharmacyProcessTypeRes getAllProcessType(PharmacyProcessTypeRes res) {
        if (res == null) {
            res = new PharmacyProcessTypeRes();
            List<PharFryingOneRule> pharFryingOneRule = getPharFryingOneRule(getType(1));
            List<PharFryingTwoRule> pharFryingTwoRules = getPharFryingTwoRule(getType(2));
            res.setPharFryingOneRules(pharFryingOneRule);
            res.setPharFryingTwoRules(pharFryingTwoRules);
        } else {//查看类型1的加工方式是否齐全
            List<PharFryingOneRule> oneRuleList = res.getPharFryingOneRules();
            if (CollectionUtils.isEmpty(oneRuleList)) {
                List<PharFryingOneRule> pharFryingOneRuleList = getPharFryingOneRule(getType(1));
                res.setPharFryingOneRules(pharFryingOneRuleList);
            } else {
                List<Integer> listA = oneRuleList.stream().map(PharFryingOneRule::getType).collect(Collectors.toList());
                List<Integer> listB = getType(1);
                //求差集
                listB.removeAll(listA);
                if (CollectionUtil.isNotEmpty(listB)) {
                    List<PharFryingOneRule> pharFryingOneRules = getPharFryingOneRule(listB);
                    oneRuleList.addAll(pharFryingOneRules);
                    res.setPharFryingOneRules(oneRuleList);
                }
            }
            List<PharFryingTwoRule> pharFryingTwoRules = res.getPharFryingTwoRules();
            if (CollectionUtil.isEmpty(pharFryingTwoRules)) {
                List<PharFryingTwoRule> pharFryingTwoRuleList = getPharFryingTwoRule(getType(2));
                res.setPharFryingTwoRules(pharFryingTwoRuleList);
            } else {
                List<Integer> listA = pharFryingTwoRules.stream().map(PharFryingTwoRule::getType).collect(Collectors.toList());
                List<Integer> listB = getType(2);
                //求交集
                listB.removeAll(listA);
                if (CollectionUtil.isNotEmpty(listB)) {
                    List<PharFryingTwoRule> pharFryingOneRules = getPharFryingTwoRule(listB);
                    pharFryingTwoRules.addAll(pharFryingOneRules);
                    res.setPharFryingTwoRules(pharFryingTwoRules);
                }
            }
        }
        return res;
    }

    public List<Integer> getType(Integer type) {
        if (type == 1) {
            List<Integer> list = new ArrayList<>();
            list.add(PresConstants.DrugsProcessingType.ONE);
            list.add(PresConstants.DrugsProcessingType.TWO);
            list.add(PresConstants.DrugsProcessingType.THREE);
            return list;
        } else if (type == 2) {
            List<Integer> list = new ArrayList<>();
            list.add(PresConstants.DrugsProcessingType.FOUR);
            list.add(PresConstants.DrugsProcessingType.FIVE);
            list.add(PresConstants.DrugsProcessingType.SIX);
            list.add(PresConstants.DrugsProcessingType.SEVEN);
            list.add(PresConstants.DrugsProcessingType.EIGHT);
            list.add(PresConstants.DrugsProcessingType.NINE);
            list.add(PresConstants.DrugsProcessingType.TEN);
            list.add(PresConstants.DrugsProcessingType.ELEVEN);
            list.add(PresConstants.DrugsProcessingType.TWELVE);
            list.add(PresConstants.DrugsProcessingType.THIRTEEN);
            list.add(PresConstants.DrugsProcessingType.FOURTEEN);
            list.add(PresConstants.DrugsProcessingType.FIFTEEN);
            list.add(PresConstants.DrugsProcessingType.SIXTEEN);
            return list;
        }
        return new ArrayList<>();
    }

    public List<PharFryingOneRule> getPharFryingOneRule(List<Integer> integers) {
        List<PharFryingOneRule> oneRules = new ArrayList<>();
        for (Integer type : integers) {
            PharFryingOneRule oneRule = new PharFryingOneRule();
            oneRule.setIsChecked(0);
            oneRule.setFreeIsChecked(0);
            oneRule.setFullDoseIsChecked(0);
            oneRule.setFullDose(1);
            oneRule.setDoseIsChecked(0);
            oneRule.setDose(1);
            oneRule.setType(type);
            oneRules.add(oneRule);
        }
        return oneRules;
    }

    public List<PharFryingTwoRule> getPharFryingTwoRule(List<Integer> types) {
        List<PharFryingTwoRule> twoRules = new ArrayList<>();
        for (Integer type : types) {
            PharFryingTwoRule twoRule = new PharFryingTwoRule();
            twoRule.setIsChecked(0);
            twoRule.setReWeightIsChecked(0);
            twoRule.setRealWeightIsChecked(0);
            twoRule.setFreeIsChecked(0);
            twoRule.setMinWeightIsChecked(0);
            twoRule.setProcessKg(1);
            twoRule.setType(type);
            twoRules.add(twoRule);
        }
        return twoRules;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePharmacyExpFee(PharExpRuleRes pharExpRuleRes) {
        log.info("物流参数===========>" + JSON.toJSONString(pharExpRuleRes));
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.PHAR).get();
        //查询物流设置信息
        LambdaQueryWrapper<PharExpressRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PharExpressRule::getPharId, loginInfo.getPharId());
        PharExpressRule oldPharExpressRule = pharExpressRuleService.getOne(wrapper);
        if (pharExpRuleRes.getDeliverWay() == 1) {
            //参数校验
            checkedOneRule(pharExpRuleRes);
            PharExpOneRule newPharExpOneRule = new PharExpOneRule();
            newPharExpOneRule.setProvince(pharExpRuleRes.getProvince());
            newPharExpOneRule.setCity(pharExpRuleRes.getCity());
            newPharExpOneRule.setDeliverWay(pharExpRuleRes.getDeliverWay());
            newPharExpOneRule.setProvincialOutFee(pharExpRuleRes.getProvincialOutFee());
            newPharExpOneRule.setCityFee(pharExpRuleRes.getCityFee());
            newPharExpOneRule.setCityOutFee(pharExpRuleRes.getCityOutFee());
            newPharExpOneRule.setIsChecked(pharExpRuleRes.getIsChecked());
            newPharExpOneRule.setFee(pharExpRuleRes.getFee());
            PharExpOneRule oldPharExpOneRule = null;
            if (ObjectUtil.isNull(oldPharExpressRule)) {
                //记录对比
                saveExpRecord(newPharExpOneRule, oldPharExpOneRule, loginInfo);
                oldPharExpressRule = new PharExpressRule();
                //设置快递到付默认值为1
                oldPharExpressRule.setIsInnerProvincialChecked(0)
                        .setIsInnerCityChecked(0)
                        .setIsOutProvincialChecked(0);
                BeanUtils.copyProperties(newPharExpOneRule, oldPharExpressRule);
                oldPharExpressRule.setPharId(loginInfo.getPharId());
                oldPharExpressRule.setUpdateDate(LocalDateTime.now());
                pharExpressRuleService.save(oldPharExpressRule);
            } else {
                oldPharExpOneRule = new PharExpOneRule();
                oldPharExpOneRule.setProvince(oldPharExpressRule.getProvince());
                oldPharExpOneRule.setCity(oldPharExpressRule.getCity());
                oldPharExpOneRule.setDeliverWay(oldPharExpressRule.getDeliverWay());
                oldPharExpOneRule.setProvincialOutFee(oldPharExpressRule.getProvincialOutFee());
                oldPharExpOneRule.setCityFee(oldPharExpressRule.getCityFee());
                oldPharExpOneRule.setCityOutFee(oldPharExpressRule.getCityOutFee());
                oldPharExpOneRule.setIsChecked(oldPharExpressRule.getIsChecked());
                oldPharExpOneRule.setFee(oldPharExpressRule.getFee());
                //记录对比
                saveExpRecord(newPharExpOneRule, oldPharExpOneRule, loginInfo);
                BeanUtils.copyProperties(newPharExpOneRule, oldPharExpressRule);
                oldPharExpressRule.setUpdateDate(LocalDateTime.now());
                pharExpressRuleService.updateById(oldPharExpressRule);
            }
        } else if (pharExpRuleRes.getDeliverWay() == 2) {
            //参数校验
            checkedTwoRule(pharExpRuleRes);
            PharExpTwoRule newPharExpTwoRule = new PharExpTwoRule();
            newPharExpTwoRule.setProvince(pharExpRuleRes.getProvince());
            newPharExpTwoRule.setCity(pharExpRuleRes.getCity());
            newPharExpTwoRule.setDeliverWay(pharExpRuleRes.getDeliverWay());
            newPharExpTwoRule.setIsInnerCityChecked(pharExpRuleRes.getIsInnerCityChecked());
            newPharExpTwoRule.setInnerCityFee(pharExpRuleRes.getInnerCityFee());
            newPharExpTwoRule.setIsInnerProvincialChecked(pharExpRuleRes.getIsInnerProvincialChecked());
            newPharExpTwoRule.setInnerProvincialFee(pharExpRuleRes.getInnerProvincialFee());
            newPharExpTwoRule.setIsOutProvincialChecked(pharExpRuleRes.getIsOutProvincialChecked());
            newPharExpTwoRule.setIsOutProvincialFee(pharExpRuleRes.getIsOutProvincialFee());
            PharExpTwoRule oldPharExpTwoRule = null;
            if (ObjectUtil.isNull(oldPharExpressRule)) {
                //记录对比
                saveExpTwoRecord(newPharExpTwoRule, oldPharExpTwoRule, loginInfo);
                oldPharExpressRule = new PharExpressRule();
                //设置快递邮寄默认值为1
                oldPharExpressRule.setFee(0)
                        .setCityOutFee(0)
                        .setCity("深圳市")
                        .setProvince("广东省")
                        .setProvincialOutFee(0)
                        .setCityFee(0)
                        .setIsChecked(0);
                BeanUtils.copyProperties(newPharExpTwoRule, oldPharExpressRule);
                oldPharExpressRule.setPharId(loginInfo.getPharId());
                oldPharExpressRule.setUpdateDate(LocalDateTime.now());
                pharExpressRuleService.save(oldPharExpressRule);
            } else {
                oldPharExpTwoRule = new PharExpTwoRule();
                BeanUtils.copyProperties(oldPharExpressRule, oldPharExpTwoRule);
                //记录对比
                saveExpTwoRecord(newPharExpTwoRule, oldPharExpTwoRule, loginInfo);
                BeanUtils.copyProperties(newPharExpTwoRule, oldPharExpressRule);
                oldPharExpressRule.setUpdateDate(LocalDateTime.now());
                pharExpressRuleService.updateById(oldPharExpressRule);
            }
        }
    }

    private void saveExpTwoRecord(PharExpTwoRule newPharExpTwoRule, PharExpTwoRule oldPharExpTwoRule, LoginInfo loginInfo) {
        PharExpTwoRule convertPharExpRule = new PharExpTwoRule();
        BeanUtils.copyProperties(newPharExpTwoRule, convertPharExpRule);
        PharExpTwoRecordRes newPharExpRecordRes = convertExpTwoData(convertPharExpRule);
        if (ObjectUtil.isNull(oldPharExpTwoRule)) {
            oldPharExpTwoRule = new PharExpTwoRule();
            oldPharExpTwoRule
                    .setCity("深圳市")
                    .setProvince("广东省")
                    .setIsInnerCityChecked(0)
                    .setIsOutProvincialChecked(0)
                    .setIsInnerProvincialChecked(0)
                    .setDeliverWay(2);
        }
        BeanUtils.copyProperties(oldPharExpTwoRule, convertPharExpRule);
        PharExpTwoRecordRes oldPharExpRecordRes = convertExpTwoData(convertPharExpRule);
        String recordRes = com.dd.cloud.common.utils.BeanUtils.getChangedFields(oldPharExpRecordRes, newPharExpRecordRes);
        if (StringUtils.isNotBlank(recordRes)) {
            recordRes = recordRes.substring(0, recordRes.length() - 1);
            PharSetFeeRecord pharSetFeeRecord = new PharSetFeeRecord();
            pharSetFeeRecord.setPharId(loginInfo.getPharId())
                    .setType(1)
                    .setUpdateContent(recordRes)
                    .setUpdateName(loginInfo.getName())
                    .setUpdateDate(LocalDateTime.now());
            pharSetFeeRecordService.save(pharSetFeeRecord);
        }
    }

    private PharExpTwoRecordRes convertExpTwoData(PharExpTwoRule convertPharExpRule) {
        convertPharExpRule.setIsOutProvincialChecked(convertPharExpRule.getIsOutProvincialChecked() == null ? 1 : convertPharExpRule.getIsOutProvincialChecked())
                .setIsInnerCityChecked(convertPharExpRule.getIsInnerCityChecked() == null ? 1 : convertPharExpRule.getIsInnerCityChecked())
                .setIsInnerProvincialChecked(convertPharExpRule.getIsInnerProvincialChecked() == null ? 1 : convertPharExpRule.getIsInnerProvincialChecked());
        PharExpTwoRecordRes newPharExpTwoRecordRes = new PharExpTwoRecordRes();
        if (convertPharExpRule.getInnerCityFee() == null) {
            newPharExpTwoRecordRes.setInnerCityFee("未填写");
        } else {
            newPharExpTwoRecordRes.setInnerCityFee(BigDecimalUtils.divide(new BigDecimal(convertPharExpRule.getInnerCityFee()), new BigDecimal(100), 2) + "元");
        }
        if (convertPharExpRule.getInnerProvincialFee() == null) {
            newPharExpTwoRecordRes.setInnerProvincialFee("未填写");
        } else {
            newPharExpTwoRecordRes.setInnerProvincialFee(BigDecimalUtils.divide(new BigDecimal(convertPharExpRule.getInnerProvincialFee()), new BigDecimal(100), 2) + "元");
        }
        if (convertPharExpRule.getIsOutProvincialFee() == null) {
            newPharExpTwoRecordRes.setIsOutProvincialFee("未填写");
        } else {
            newPharExpTwoRecordRes.setIsOutProvincialFee(BigDecimalUtils.divide(new BigDecimal(convertPharExpRule.getIsOutProvincialFee()), new BigDecimal(100), 2) + "元");
        }
        newPharExpTwoRecordRes.setProvince(convertPharExpRule.getProvince())
                .setCity(convertPharExpRule.getCity())
                .setIsInnerProvincialChecked(convertPharExpRule.getIsInnerProvincialChecked() == 1 ? "已勾选" : "未勾选")
                .setIsOutProvincialChecked(convertPharExpRule.getIsOutProvincialChecked() == 1 ? "已勾选" : "未勾选")
                .setDeliveryWay(convertPharExpRule.getDeliverWay() == 1 ? "快递邮寄" : "快递到付")
                .setIsInnerCityChecked(convertPharExpRule.getIsInnerCityChecked() == 1 ? "已勾选" : "未勾选");
        return newPharExpTwoRecordRes;
    }

    private void checkedTwoRule(PharExpRuleRes pharExpRuleRes) {
        if (pharExpRuleRes.getIsInnerCityChecked() == null) {
            throw new ZekeException("市内免快递费勾选不能为空");
        }
        if (pharExpRuleRes.getIsInnerProvincialChecked() == null) {
            throw new ZekeException("省内外免快递费勾选不能为空");
        }
        if (pharExpRuleRes.getIsOutProvincialChecked() == null) {
            throw new ZekeException("省外免快递费勾选不能为空");
        }
        if (pharExpRuleRes.getIsInnerCityChecked() == 1
                && pharExpRuleRes.getInnerCityFee() == null) {
            throw new ZekeException("市内免快递费不能为空");
        }
        if (pharExpRuleRes.getIsInnerProvincialChecked() == 1
                && pharExpRuleRes.getInnerProvincialFee() == null) {
            throw new ZekeException("省内外免快递费不能为空");
        }
        if (pharExpRuleRes.getIsOutProvincialChecked() == 1
                && pharExpRuleRes.getIsOutProvincialFee() == null) {
            throw new ZekeException("省外免快递费不能为空");
        }
    }

    private void checkedOneRule(PharExpRuleRes pharExpRuleRes) {
        if (pharExpRuleRes.getProvincialOutFee() == null) {
            throw new ZekeException("省外快递费不能为空");
        }
        if (pharExpRuleRes.getCityFee() == null) {
            throw new ZekeException("市内快递费不能为空");
        }
        if (pharExpRuleRes.getCityOutFee() == null) {
            throw new ZekeException("市外快递不能为空");
        }
        if (pharExpRuleRes.getIsChecked() == null) {
            throw new ZekeException("是否勾选不能为空");
        }
    }


    @Override
    public void updatePharmacyFryFee(PharFryRuleReq pharFryRuleReq) {
        List<PharFryingOneRuleReq> newOneRuleList = pharFryRuleReq.getPharFryingOneRuleList();
        List<PharFryingTwoRuleReq> newTwoRuleList = pharFryRuleReq.getPharFryingTwoRuleList();
        checkedOneType(newOneRuleList);
        checkedTwoType(newTwoRuleList);
        checkedType(newTwoRuleList);
        log.info("第一种参数======>" + JSON.toJSONString(newOneRuleList));
        log.info("第二种参数======>" + JSON.toJSONString(newTwoRuleList));
        List<String> newRuleTypeListStr = newOneRuleList.stream().map(PharFryingOneRuleReq::getType).collect(Collectors.toList())
                .stream().map(String::valueOf).collect(Collectors.toList());
        List<String> oldRuleTypeListStr = PresConstants.DrugsProcessingType.oneRulesStr;
        log.info("传入的第一种加工方式参数:" + newRuleTypeListStr + "默认的加工方式参数:" + oldRuleTypeListStr);
        Boolean oneFlag = checkDiffrent4(newRuleTypeListStr, oldRuleTypeListStr);
        if (!oneFlag) {
            throw new ZekeException("缺少传递的加工类型");
        }
        List<String> newTwoRuleTypeListStr = newTwoRuleList.stream().map(PharFryingTwoRuleReq::getType).collect(Collectors.toList())
                .stream().map(String::valueOf).collect(Collectors.toList());
        List<String> oldTwoRuleTypeListStr = PresConstants.DrugsProcessingType.twoRulesStr;
        log.info("传入的第二种加工方式参数:" + newTwoRuleTypeListStr + "默认的加工方式参数:" + oldTwoRuleTypeListStr);
        Boolean twoFlag = checkDiffrent4(newTwoRuleTypeListStr, oldTwoRuleTypeListStr);
        if (!twoFlag) {
            throw new ZekeException("缺少传递的加工类型");
        }
        log.info("代煎+饮片加工参数===========>" + JSON.toJSONString(newOneRuleList));
        log.info("其他加工类型参数===========>" + JSON.toJSONString(newTwoRuleList));
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.PHAR).get();
//        LoginInfo loginInfo = new LoginInfo();
//        loginInfo.setPharId(3);
//        loginInfo.setId(1);
        List<PharFryingOneRule> newOneRules = new ArrayList<>();
        for (PharFryingOneRuleReq fryingOneRuleReq : newOneRuleList) {
            PharFryingOneRule pharFryingOneRule = new PharFryingOneRule();
            pharFryingOneRule.setProcessingFee(fryingOneRuleReq.getProcessingFee())
                    .setIsChecked(fryingOneRuleReq.getIsChecked())
                    .setFreeIsChecked(fryingOneRuleReq.getFreeIsChecked())
                    .setDrugFee(fryingOneRuleReq.getDrugFee())
                    .setFullDoseIsChecked(fryingOneRuleReq.getFullDoseIsChecked())
                    .setFullDose(fryingOneRuleReq.getFullDose())
                    .setFullDoseCharge(fryingOneRuleReq.getFullDoseCharge())
                    .setDoseIsChecked(fryingOneRuleReq.getDoseIsChecked())
                    .setDose(fryingOneRuleReq.getDose())
                    .setDoseCharge(fryingOneRuleReq.getDoseCharge())
                    .setType(fryingOneRuleReq.getType());
            newOneRules.add(pharFryingOneRule);
        }
        List<PharFryingTwoRule> newTwoRules = new ArrayList<>();
        for (PharFryingTwoRuleReq fryingTwoRuleReq : newTwoRuleList) {
            PharFryingTwoRule pharFryingTwoRule = new PharFryingTwoRule();
            pharFryingTwoRule.setIsChecked(fryingTwoRuleReq.getIsChecked())
                    .setProcessingFee(fryingTwoRuleReq.getProcessingFee())
                    .setReWeightIsChecked(fryingTwoRuleReq.getReWeightIsChecked())
                    .setReWeight(fryingTwoRuleReq.getReWeight())
                    .setWeightFee(fryingTwoRuleReq.getWeightFee())
                    .setMinRate(fryingTwoRuleReq.getMinRate())
                    .setMaxRate(fryingTwoRuleReq.getMaxRate())
                    .setRealWeightIsChecked(fryingTwoRuleReq.getRealWeightIsChecked())
                    .setFreeIsChecked(fryingTwoRuleReq.getFreeIsChecked())
                    .setDrugFee(fryingTwoRuleReq.getDrugFee())
                    .setMinWeightIsChecked(fryingTwoRuleReq.getMinWeightIsChecked())
                    .setMinWeight(fryingTwoRuleReq.getMinWeight())
                    .setType(fryingTwoRuleReq.getType())
                    .setProcessKg(fryingTwoRuleReq.getProcessKg());
            newTwoRules.add(pharFryingTwoRule);
        }
        //查询物流设置信息
        LambdaQueryWrapper<PharFryingOneRule> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PharFryingOneRule::getPharId, loginInfo.getPharId())
                .eq(PharFryingOneRule::getStatus, 1);
        List<PharFryingOneRule> oldOneRuleList = pharFryingOneRuleService.getBaseMapper().selectList(wrapper);
        List<PharFryingOneRule> oldOneRuleListArray = oldOneRuleList;
        if (CollectionUtil.isEmpty(oldOneRuleList)) {
            oldOneRuleList = getPharFryingOneRule(PresConstants.DrugsProcessingType.oneRules);
        }
        //饮片+代煎记录对比
        String oneRuleRes = saveFryOneRuleRecord(oldOneRuleList, newOneRules);
        LambdaQueryWrapper<PharFryingTwoRule> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PharFryingTwoRule::getPharId, loginInfo.getPharId())
                .eq(PharFryingTwoRule::getStatus, 1);
        List<PharFryingTwoRule> oldTwoRuleList = pharFryingTwoRuleService.getBaseMapper().selectList(queryWrapper);
        List<PharFryingTwoRule> oldTwoRuleListArray = oldTwoRuleList;
        if (CollectionUtil.isEmpty(oldTwoRuleList)) {
            oldTwoRuleList = getPharFryingTwoRule(PresConstants.DrugsProcessingType.twoRules);
        }
        //其他代煎类型对比
        String twoRuleRes = saveFryTwoRuleRecord(oldTwoRuleList, newTwoRules);
        String result = oneRuleRes + twoRuleRes;
        //对比备注
        String remark = (String) redisTemplate.opsForValue().get(PHAR_FRYING_REMARK + loginInfo.getPharId());
        PharFryRemarkRes oldPharFryRemarkRes = new PharFryRemarkRes();
        PharFryRemarkRes newPharFryRemarkRes = new PharFryRemarkRes();
        oldPharFryRemarkRes.setRemark(remark == null ? "未设置" : remark);
        newPharFryRemarkRes.setRemark(pharFryRuleReq.getRemark() == null ? "未设置" : pharFryRuleReq.getRemark());
        String remarkRes = com.dd.cloud.common.utils.BeanUtils.getChangedFields(oldPharFryRemarkRes, newPharFryRemarkRes);
        if (StringUtils.isNotBlank(remarkRes)) {
            result += remarkRes;
        }
        if (StringUtils.isNotBlank(result)) {
            result = result.substring(0, result.length() - 1);
            PharSetFeeRecord pharSetFeeRecord = new PharSetFeeRecord();
            pharSetFeeRecord.setPharId(loginInfo.getPharId())
                    .setType(2)
                    .setUpdateContent(result)
                    .setUpdateName(loginInfo.getName())
                    .setUpdateDate(LocalDateTime.now());
            pharSetFeeRecordService.save(pharSetFeeRecord);
        }
        //先逻辑删除
        LambdaUpdateWrapper<PharFryingOneRule> oneUpdateWrapper = new LambdaUpdateWrapper<>();
        oneUpdateWrapper.eq(PharFryingOneRule::getPharId, loginInfo.getPharId())
                .set(PharFryingOneRule::getStatus, -1);
        pharFryingOneRuleService.update(oneUpdateWrapper);
        LambdaUpdateWrapper<PharFryingTwoRule> twoUpdateWrapper = new LambdaUpdateWrapper<>();
        twoUpdateWrapper.eq(PharFryingTwoRule::getPharId, loginInfo.getPharId())
                .set(PharFryingTwoRule::getStatus, -1);
        pharFryingTwoRuleService.update(twoUpdateWrapper);
        //删除redis中的备注
        stringRedisTemplate.delete(PHAR_FRYING_REMARK + loginInfo.getPharId());
        List<Integer> oneRules = getType(1);
        List<Integer> twoRules = getType(2);
        //过滤掉默认的值
        List<PharFryingOneRule> defaultPharFryingOneRuleList = getPharFryingOneRule(oneRules);
        Map<Integer, PharFryingOneRule> defaultOneRuleMaps = defaultPharFryingOneRuleList.stream()
                .collect(Collectors.toMap(PharFryingOneRule::getType, Function.identity()));
        Map<Integer, PharFryingOneRule> newOneRuleMaps = newOneRules.stream().collect(Collectors.toMap(PharFryingOneRule::getType,
                Function.identity()));
        List<PharFryingOneRule> oneRuleArrayList = new ArrayList<>();
        for (Integer type : oneRules) {
            PharFryingOneRule defaultPharFryingOneRule = defaultOneRuleMaps.get(type);
            PharFryingOneRule newOneRule = newOneRuleMaps.get(type);
            Boolean flag = ClassCompareUtil.compareObject(defaultPharFryingOneRule, newOneRule);
            if (!flag) {
                newOneRule.setPharId(loginInfo.getPharId())
                        .setUpdateDate(LocalDateTime.now())
                        .setStatus(1);
                oneRuleArrayList.add(newOneRule);
            }
        }
        List<PharFryingTwoRule> defaultPharFryingTwoRuleList = getPharFryingTwoRule(twoRules);
        Map<Integer, PharFryingTwoRule> defaultTwoRuleMaps = defaultPharFryingTwoRuleList.stream()
                .collect(Collectors.toMap(PharFryingTwoRule::getType, Function.identity()));
        Map<Integer, PharFryingTwoRule> newTwoRuleMaps = newTwoRules.stream().collect(Collectors.toMap(PharFryingTwoRule::getType, Function.identity()));
        List<PharFryingTwoRule> twoRuleArrayList = new ArrayList<>();
        for (Integer type : twoRules) {
            PharFryingTwoRule defaultPharFryingTwoRule = defaultTwoRuleMaps.get(type);
            PharFryingTwoRule newTwoRule = newTwoRuleMaps.get(type);
            Boolean flag = ClassCompareUtil.compareObject(defaultPharFryingTwoRule, newTwoRule);
            if (!flag) {
                newTwoRule.setPharId(loginInfo.getPharId())
                        .setUpdateDate(LocalDateTime.now())
                        .setStatus(1);
                twoRuleArrayList.add(newTwoRule);
            }
        }
        List<PharFryingOneRule> updatePharOneRuleList = new ArrayList<>();
        List<PharFryingOneRule> addPharOneRuleList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(oneRuleArrayList)) {
            if (CollectionUtil.isNotEmpty(oldOneRuleListArray)) {
                //如果存在此类型则更新此值,若不存在则添加
                List<Integer> typeArray = oneRuleArrayList.stream().map(PharFryingOneRule::getType).distinct().collect(Collectors.toList());
                Map<Integer, PharFryingOneRule> newOneRuleMap = oneRuleArrayList.stream().collect(Collectors.toMap(PharFryingOneRule::getType, Function.identity()));
                Map<Integer, PharFryingOneRule> oldOneRuleMap = oldOneRuleListArray.stream().collect(Collectors.toMap(PharFryingOneRule::getType, Function.identity()));
                for (Integer type : typeArray) {
                    PharFryingOneRule oldPharFryingOneRule = oldOneRuleMap.get(type);
                    PharFryingOneRule newPharFryingOneRule = newOneRuleMap.get(type);
                    if (oldPharFryingOneRule != null) {
                        Integer oneRuleId = oldPharFryingOneRule.getId();
                        BeanUtils.copyProperties(newPharFryingOneRule, oldPharFryingOneRule);
                        oldPharFryingOneRule.setId(oneRuleId);
                        updatePharOneRuleList.add(oldPharFryingOneRule);
                    } else {
                        addPharOneRuleList.add(newPharFryingOneRule);
                    }
                }
                if (CollectionUtil.isNotEmpty(updatePharOneRuleList)) {
                    pharFryingOneRuleService.updateBatchById(updatePharOneRuleList);
                }
                if (CollectionUtil.isNotEmpty(addPharOneRuleList)) {
                    pharFryingOneRuleService.saveBatch(addPharOneRuleList);
                }
            } else {
                pharFryingOneRuleService.saveBatch(oneRuleArrayList);
            }
        }
        List<PharFryingTwoRule> updatePharTwoRuleList = new ArrayList<>();
        List<PharFryingTwoRule> addPharTwoRuleList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(twoRuleArrayList)) {
            if (CollectionUtil.isNotEmpty(oldTwoRuleListArray)) {
                //如果存在此类型则更新此值,若不存在则添加
                List<Integer> typeArray = twoRuleArrayList.stream().map(PharFryingTwoRule::getType).distinct().collect(Collectors.toList());
                Map<Integer, PharFryingTwoRule> newTwoRuleMap = twoRuleArrayList.stream().collect(Collectors.toMap(PharFryingTwoRule::getType, Function.identity()));
                Map<Integer, PharFryingTwoRule> oldTwoRuleMap = oldTwoRuleListArray.stream().collect(Collectors.toMap(PharFryingTwoRule::getType, Function.identity()));
                for (Integer type : typeArray) {
                    PharFryingTwoRule oldPharFryingTwoRule = oldTwoRuleMap.get(type);
                    PharFryingTwoRule newPharFryingTwoRule = newTwoRuleMap.get(type);
                    if (oldPharFryingTwoRule != null) {
                        Integer twoRuleId = oldPharFryingTwoRule.getId();
                        BeanUtils.copyProperties(newPharFryingTwoRule, oldPharFryingTwoRule);
                        oldPharFryingTwoRule.setId(twoRuleId);
                        updatePharTwoRuleList.add(oldPharFryingTwoRule);
                    } else {
                        addPharTwoRuleList.add(newPharFryingTwoRule);
                    }
                }
                if (CollectionUtil.isNotEmpty(updatePharTwoRuleList)) {
                    pharFryingTwoRuleService.updateBatchById(updatePharTwoRuleList);
                }
                if (CollectionUtil.isNotEmpty(addPharTwoRuleList)) {
                    pharFryingTwoRuleService.saveBatch(addPharTwoRuleList);
                }
            } else {
                pharFryingTwoRuleService.saveBatch(twoRuleArrayList);
            }
        }
        if (StringUtils.isNotBlank(pharFryRuleReq.getRemark())) {
            stringRedisTemplate.opsForValue().set(PHAR_FRYING_REMARK + loginInfo.getPharId(), pharFryRuleReq.getRemark());
        }
    }

    private void checkedType(List<PharFryingTwoRuleReq> newTwoRuleList) {
        for (PharFryingTwoRuleReq pharFryingTwoRule : newTwoRuleList) {
            if (pharFryingTwoRule.getIsChecked() == 1
                    && pharFryingTwoRule.getReWeightIsChecked() == 0
                    && pharFryingTwoRule.getRealWeightIsChecked() == 0) {
                String strType = getStrType(pharFryingTwoRule.getType());
                throw new ZekeException(strType + "缺少续重或按实际重量勾选,请任选其一");
            }
        }
    }

    private void checkedOneType(List<PharFryingOneRuleReq> newOneRuleList) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer pharId = loginInfo.getPharId();
        Integer flag = pharmacyService.getPharmacyFlag(pharId);
        for (PharFryingOneRuleReq pharFryingOneRule : newOneRuleList) {
            Integer type = pharFryingOneRule.getType();
            Integer isChecked = pharFryingOneRule.getIsChecked();
            String strType = getStrType(type);
            if (flag != PharConstants.Flag.YF) {
                if (type == PresConstants.DrugsProcessingType.THREE && isChecked == 1) {
                    throw new ZekeException("该药房暂不支持" + strType + "加工类型");
                }
            }
            if (flag == PharConstants.Flag.YF) {
                if (type == PresConstants.DrugsProcessingType.ONE && isChecked == 1) {
                    throw new ZekeException("该药房暂不支持" + strType + "加工类型");
                } else if (type == PresConstants.DrugsProcessingType.TWO && isChecked == 1) {
                    throw new ZekeException("该药房暂不支持" + strType + "加工类型");
                }
            }
        }
    }

    private void checkedTwoType(List<PharFryingTwoRuleReq> newTwoRuleList) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer pharId = loginInfo.getPharId();
        Integer flag = pharmacyService.getPharmacyFlag(pharId);
        if (flag == PharConstants.Flag.YF) {//一方制药颗粒剂
            for (PharFryingTwoRuleReq pharFryingTwoRuleReq : newTwoRuleList) {
                Integer type = pharFryingTwoRuleReq.getType();
                Integer isChecked = pharFryingTwoRuleReq.getIsChecked();
                String strType = getStrType(type);
                if (isChecked == 1) {
                    throw new ZekeException("该药房暂不支持" + strType + "加工类型");
                }
            }
        } else if (flag == PharConstants.Flag.HJT) {//否则为宏济堂 那么可以设置宏济堂相关的类型
            for (PharFryingTwoRuleReq pharFryingTwoRuleReq : newTwoRuleList) {
                Integer type = pharFryingTwoRuleReq.getType();
                Integer isChecked = pharFryingTwoRuleReq.getIsChecked();
                String strType = getStrType(type);
                if (type == PresConstants.DrugsProcessingType.NINE && isChecked == 1) {
                    throw new ZekeException("该药房暂不支持" + strType + "加工类型");
                } else if (type == PresConstants.DrugsProcessingType.THREE && isChecked == 1) {
                    throw new ZekeException("该药房暂不支持" + strType + "加工类型");
                } else if (type == PresConstants.DrugsProcessingType.THIRTEEN && isChecked == 1) {
                    throw new ZekeException("该药房暂不支持" + strType + "加工类型");
                } else if (type == PresConstants.DrugsProcessingType.SIXTEEN && isChecked == 1) {
                    throw new ZekeException("该药房暂不支持" + strType + "加工类型");
                }
            }
        } else {
            for (PharFryingTwoRuleReq pharFryingTwoRule : newTwoRuleList) {
                if (pharFryingTwoRule.getIsChecked() == 1) {
                    Integer type = pharFryingTwoRule.getType();
                    String res = getStrType(type);
                    throw new ZekeException("该药房暂不支持" + res + "加工类型");
                }
            }
        }
    }

    private static boolean checkDiffrent4(List<String> list, List<String> list1) {
        long st = System.nanoTime();
        System.out.println("消耗时间为： " + (System.nanoTime() - st));
        /** 先将集合转成stream流进行排序然后转成字符串进行比较 */
        return list.stream().sorted().collect(Collectors.joining())
                .equals(list1.stream().sorted().collect(Collectors.joining()));
    }

    private String saveFryTwoRuleRecord(List<PharFryingTwoRule> oldTwoRuleList, List<PharFryingTwoRule> newTwoRuleList) {
        //转换数据
        List<PharFryTwoRuleRecordRes> oldTwoRuleRecordResList = convertTwoRuleData(oldTwoRuleList);
        List<PharFryTwoRuleRecordRes> newTwoRuleRecordResList = convertTwoRuleData(newTwoRuleList);
        Map<Integer, PharFryTwoRuleRecordRes> oldTwoRuleMaps = oldTwoRuleRecordResList.stream()
                .collect(Collectors.toMap(PharFryTwoRuleRecordRes::getType, Function.identity()));
        Map<Integer, PharFryTwoRuleRecordRes> newTwoRuleMaps = newTwoRuleRecordResList.stream()
                .collect(Collectors.toMap(PharFryTwoRuleRecordRes::getType, Function.identity()));
        List<Integer> types = PresConstants.DrugsProcessingType.twoRules;
        StringBuffer sb = new StringBuffer();
        for (Integer type : types) {
            PharFryTwoRuleRecordRes oldValue = oldTwoRuleMaps.get(type);
            PharFryTwoRuleRecordRes newValue = newTwoRuleMaps.get(type);
            if (oldValue == null || newValue == null) {
                continue;
            }
            String res = com.dd.cloud.common.utils.BeanUtils.getChangedFields(oldValue, newValue);
            if (StringUtils.isNotBlank(res)) {
                String strType = getStrType(type);
                sb.append(strType);
                res = res.substring(0, res.length() - 1);
                sb.append(res + "&nbsp;<br />");
            }
        }
        String result = sb.toString();
        if (StringUtils.isBlank(result)) {
            return "";
        }
        return result;
    }

    public String getStrType(Integer type) {
        //类型 1.代煎 2.饮片 3.水丸 4.浓缩丸 5.水蜜丸 6.蜜丸 7.膏方 8.颗粒剂 " +
        //"9.合煎制粉(200目) 10.粉制(40目及以下) 11.粉剂(60目) 12.粉剂(80目) 13.粉剂(100目) " +
        //"14.粉剂(200目) 15.粉剂(300目及以上)
        String strType = "";
        if (type == PresConstants.DrugsProcessingType.ONE) {
            strType = "加工类型:饮片代煎 ";
        } else if (type == PresConstants.DrugsProcessingType.TWO) {
            strType = "加工类型:饮片不代煎 ";
        } else if (type == PresConstants.DrugsProcessingType.THREE) {
            strType = "加工类型:颗粒剂 ";
        } else if (type == PresConstants.DrugsProcessingType.FOUR) {
            strType = "加工类型:水丸 ";
        } else if (type == PresConstants.DrugsProcessingType.FIVE) {
            strType = "加工类型:浓缩丸 ";
        } else if (type == PresConstants.DrugsProcessingType.SIX) {
            strType = "加工类型:水蜜丸 ";
        } else if (type == PresConstants.DrugsProcessingType.SEVEN) {
            strType = "加工类型:蜜丸 ";
        } else if (type == PresConstants.DrugsProcessingType.EIGHT) {
            strType = "加工类型:膏方 ";
        } else if (type == PresConstants.DrugsProcessingType.NINE) {
            strType = "加工类型:粉剂(40目及以下)";
        } else if (type == PresConstants.DrugsProcessingType.TEN) {
            strType = "加工类型:粉制(60目)";
        } else if (type == PresConstants.DrugsProcessingType.ELEVEN) {
            strType = "加工类型:粉剂(80目)";
        } else if (type == PresConstants.DrugsProcessingType.TWELVE) {
            strType = "加工类型:粉剂(100目)";
        } else if (type == PresConstants.DrugsProcessingType.THIRTEEN) {
            strType = "加工类型:粉剂(150目)";
        } else if (type == PresConstants.DrugsProcessingType.FOURTEEN) {
            strType = "加工类型:粉剂(200目)";
        } else if (type == PresConstants.DrugsProcessingType.FIFTEEN) {
            strType = "加工类型:合煎制粉(200目)";
        } else if (type == PresConstants.DrugsProcessingType.SIXTEEN) {
            strType = "加工类型:粉剂(300目及以上)";
        }
        return strType;
    }

    private List<PharFryTwoRuleRecordRes> convertTwoRuleData(List<PharFryingTwoRule> oldTwoRuleReqList) {
        List<PharFryTwoRuleRecordRes> pharFryingTwoRules = new ArrayList<>();
        for (PharFryingTwoRule fryTwoRuleRecordRes : oldTwoRuleReqList) {
            PharFryTwoRuleRecordRes pharFryTwoRuleRecordRes = new PharFryTwoRuleRecordRes();
            pharFryTwoRuleRecordRes.setIsChecked(fryTwoRuleRecordRes.getIsChecked() == 0 ? "未勾选" : "已勾选");
            pharFryTwoRuleRecordRes.setProcessingFee(fryTwoRuleRecordRes.getProcessingFee() == null ? "未设置"
                    : BigDecimalUtils.divide(new BigDecimal(fryTwoRuleRecordRes.getProcessingFee()), new BigDecimal(100), 2) + "元");
            pharFryTwoRuleRecordRes.setReWeightIsChecked(fryTwoRuleRecordRes.getReWeightIsChecked() == 0 ? "未勾选" : "已勾选");
            pharFryTwoRuleRecordRes.setReWeight(fryTwoRuleRecordRes.getReWeight() == null ? "未设置" : fryTwoRuleRecordRes.getReWeight() + "克");
            pharFryTwoRuleRecordRes.setWeightFee(fryTwoRuleRecordRes.getWeightFee() == null ? "未设置"
                    : BigDecimalUtils.divide(new BigDecimal(fryTwoRuleRecordRes.getWeightFee()), new BigDecimal(100), 2) + "元");
            pharFryTwoRuleRecordRes.setMinRate(fryTwoRuleRecordRes.getMinRate() == null ? "未设置" : fryTwoRuleRecordRes.getMinRate() + "");
            pharFryTwoRuleRecordRes.setMaxRate(fryTwoRuleRecordRes.getMaxRate() == null ? "未设置" : fryTwoRuleRecordRes.getMaxRate() + "");
            pharFryTwoRuleRecordRes.setRealWeightIsChecked(fryTwoRuleRecordRes.getRealWeightIsChecked() == 0 ? "未勾选" : "已勾选");
            pharFryTwoRuleRecordRes.setFreeIsChecked(fryTwoRuleRecordRes.getFreeIsChecked() == 0 ? "未勾选" : "已勾选");
            pharFryTwoRuleRecordRes.setDrugFee(fryTwoRuleRecordRes.getDrugFee() == null ? "未设置"
                    : BigDecimalUtils.divide(new BigDecimal(fryTwoRuleRecordRes.getDrugFee()), new BigDecimal(100), 2) + "元");
            pharFryTwoRuleRecordRes.setMinWeightIsChecked(fryTwoRuleRecordRes.getMinWeightIsChecked() == 0 ? "未勾选" : "已勾选");
            pharFryTwoRuleRecordRes.setMinWeight(fryTwoRuleRecordRes.getMinWeight() == null ? "未设置" : fryTwoRuleRecordRes.getMinWeight() + "克");
            pharFryTwoRuleRecordRes.setProcessKg(fryTwoRuleRecordRes.getProcessKg() == null ? "未设置" : fryTwoRuleRecordRes.getProcessKg() + "公斤");
            pharFryTwoRuleRecordRes.setType(fryTwoRuleRecordRes.getType());
            pharFryingTwoRules.add(pharFryTwoRuleRecordRes);
        }
        return pharFryingTwoRules;

    }

    private String saveFryOneRuleRecord(List<PharFryingOneRule> oldOneRuleList,
                                        List<PharFryingOneRule> newOneRuleReqList) {
        //转换数据
        List<PharFryOneRuleRecordRes> oldOneRuleRecordResList = convertOneRuleData(oldOneRuleList);
        List<PharFryOneRuleRecordRes> newOneRuleRecordResList = convertOneRuleData(newOneRuleReqList);
        Map<Integer, PharFryOneRuleRecordRes> oldOneRuleMaps = oldOneRuleRecordResList.stream()
                .collect(Collectors.toMap(PharFryOneRuleRecordRes::getType, Function.identity()));
        Map<Integer, PharFryOneRuleRecordRes> newOneRuleMaps = newOneRuleRecordResList.stream()
                .collect(Collectors.toMap(PharFryOneRuleRecordRes::getType, Function.identity()));
        List<Integer> types = PresConstants.DrugsProcessingType.oneRules;
        StringBuffer sb = new StringBuffer();
        for (Integer type : types) {
            PharFryOneRuleRecordRes oldRuleRes = oldOneRuleMaps.get(type);
            PharFryOneRuleRecordRes newRuleRes = newOneRuleMaps.get(type);
            if (oldRuleRes == null || newRuleRes == null) {
                continue;
            }
            String res = com.dd.cloud.common.utils.BeanUtils.getChangedFields(oldRuleRes, newRuleRes);
            if (StringUtils.isNotBlank(res)) {
                if (type == PresConstants.DrugsProcessingType.ONE) {
                    sb.append("加工类型:代煎 ");
                } else if (type == PresConstants.DrugsProcessingType.TWO) {
                    sb.append("加工类型:饮片 ");
                }
                res = res.substring(0, res.length() - 1);
                sb.append(res + "&nbsp;<br />");
            }
        }
        String result = sb.toString();
        if (StringUtils.isBlank(result)) {
            return "";
        }
        return result;
    }

    private List<PharFryOneRuleRecordRes> convertOneRuleData(List<PharFryingOneRule> ruleList) {
        List<PharFryOneRuleRecordRes> list = new ArrayList<>();
        for (PharFryingOneRule pharFryingOneRuleReq : ruleList) {
            PharFryOneRuleRecordRes pharFryOneRuleRecordRes = new PharFryOneRuleRecordRes();
            pharFryOneRuleRecordRes.setIsChecked(pharFryingOneRuleReq.getIsChecked() == 0 ? "未勾选" : "已勾选");
            pharFryOneRuleRecordRes.setProcessingFee(pharFryingOneRuleReq.getProcessingFee() == null ? "未设置"
                    : BigDecimalUtils.divide(new BigDecimal(pharFryingOneRuleReq.getProcessingFee()), new BigDecimal(100), 2) + "元");
            pharFryOneRuleRecordRes.setFreeIsChecked(pharFryingOneRuleReq.getFreeIsChecked() == 0 ? "未勾选" : "已勾选");
            pharFryOneRuleRecordRes.setDrugFee(pharFryingOneRuleReq.getDrugFee() == null ? "未设置"
                    : BigDecimalUtils.divide(new BigDecimal(pharFryingOneRuleReq.getDrugFee()), new BigDecimal(100), 2) + "元");
            pharFryOneRuleRecordRes.setFullDoseIsChecked(pharFryingOneRuleReq.getFullDoseIsChecked() == 0 ? "未勾选" : "已勾选");
            pharFryOneRuleRecordRes.setFullDose(pharFryingOneRuleReq.getFullDose() + "剂");
            pharFryOneRuleRecordRes.setFullDoseCharge(pharFryingOneRuleReq.getFullDoseCharge() == null ? "未设置"
                    : BigDecimalUtils.divide(new BigDecimal(pharFryingOneRuleReq.getFullDoseCharge()), new BigDecimal(100), 2) + "元");
            pharFryOneRuleRecordRes.setDoseIsChecked(pharFryingOneRuleReq.getDoseIsChecked() == 0 ? "未勾选" : "已勾选");
            pharFryOneRuleRecordRes.setDose(pharFryingOneRuleReq.getDose() + "剂");
            pharFryOneRuleRecordRes.setDoseCharge(pharFryingOneRuleReq.getDoseCharge() == null ? "未设置"
                    : BigDecimalUtils.divide(new BigDecimal(pharFryingOneRuleReq.getDoseCharge()), new BigDecimal(100), 2) + "元");
            pharFryOneRuleRecordRes.setType(pharFryingOneRuleReq.getType());
            list.add(pharFryOneRuleRecordRes);
        }
        return list;
    }

    @Override
    public Page<PharSetFeeRecord> getSetFeePage(PharSetReq pharSetReq) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.PHAR).get();
        Integer pharId = loginInfo.getPharId();
        LambdaQueryWrapper<PharSetFeeRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PharSetFeeRecord::getType, pharSetReq.getType())
                .eq(PharSetFeeRecord::getPharId, pharId)
                .orderByDesc(PharSetFeeRecord::getUpdateDate);
        Page<PharSetFeeRecord> page = pharSetReq.pagePojo();
        page = pharSetFeeRecordService.getBaseMapper().selectPage(page, wrapper);
        return page;
    }

    @Override
    public PharFeeRes queryFee(Integer pharId) {
        LambdaQueryWrapper<PharExpressRule> expWrapper = new LambdaQueryWrapper<>();
        expWrapper.eq(PharExpressRule::getPharId, pharId);
        PharExpressRule pharExpressRule = pharExpressRuleService.getOne(expWrapper);
        if (ObjectUtil.isNull(pharExpressRule)) {
            pharExpressRule = new PharExpressRule();
            pharExpressRule.setFee(0)
                    .setCityOutFee(0)
                    .setCity("深圳市")
                    .setProvince("广东省")
                    .setProvincialOutFee(0)
                    .setCityFee(0)
                    .setIsChecked(1)
                    .setDeliverWay(1)
                    .setIsOutProvincialChecked(1)
                    .setIsInnerProvincialChecked(1)
                    .setIsInnerCityChecked(1);
        }
        PharFeeRes pharFeeRes = new PharFeeRes();
        pharFeeRes.setPharExpRuleRes(pharExpressRule);
        return pharFeeRes;
    }

    @Override
    public void findStoreUserPwd(String phone, String code, String pwd1, String pwd2) {
        if (StringUtils.isBlank(code)) {
            throw new ZekeException(ZkExceptionEnum.INVALID_VERIFY_CODE);
        }
        if (!Objects.equals(pwd1, pwd2)) {
            throw new ZekeException(400, "两次密码不一致");
        }

        smsComponent.verifyPhoneCode(phone, code);
        String salt = CodecUtils.generateSalt();
        pwd2 = CodecUtils.md5Hex(pwd2, salt);
        UpdateWrapper<PharmacyUser> uw = new UpdateWrapper<>();
        uw.lambda().eq(PharmacyUser::getPhone, phone);
        uw.lambda().set(PharmacyUser::getSalt, salt);
        uw.lambda().set(PharmacyUser::getPassword, pwd2);
        boolean flag = update(uw);
        if (!flag) {
            throw new ZekeException(ZkExceptionEnum.ACCOUNT_NOT_FOUND);
        }
    }

    @Override
    public PharmacyProcessTypeRes getFryingFeePage() {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        PharmacyProcessTypeRes pharmacyProcessTypeRes = new PharmacyProcessTypeRes();
        LambdaQueryWrapper<PharFryingOneRule> oneWrapper = new LambdaQueryWrapper<>();
        oneWrapper.eq(PharFryingOneRule::getPharId, loginInfo.getPharId())
                .eq(PharFryingOneRule::getIsChecked, 1)
                .eq(PharFryingOneRule::getStatus, 1);
        List<PharFryingOneRule> pharFryingOneRules = pharFryingOneRuleService.getBaseMapper().selectList(oneWrapper);
        pharmacyProcessTypeRes.setPharFryingOneRules(pharFryingOneRules);
        LambdaQueryWrapper<PharFryingTwoRule> twoWrapper = new LambdaQueryWrapper<>();
        twoWrapper.eq(PharFryingTwoRule::getPharId, loginInfo.getPharId())
                .eq(PharFryingTwoRule::getIsChecked, 1)
                .eq(PharFryingTwoRule::getStatus, 1);
        List<PharFryingTwoRule> pharFryingTwoRules = pharFryingTwoRuleService.getBaseMapper().selectList(twoWrapper);
        pharmacyProcessTypeRes.setPharFryingTwoRules(pharFryingTwoRules);
        String remark = redisTemplate.opsForValue().get(PHAR_FRYING_REMARK + loginInfo.getPharId());
        pharmacyProcessTypeRes.setRemark(remark);
        pharmacyProcessTypeRes.setUpdateDate(pharFryingOneRules.get(0).getUpdateDate());
        return pharmacyProcessTypeRes;
    }


    @Override
    public List<PharOneRuleFeeRes> getOneRuleList(String types, Integer pharId) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer mechanId = loginInfo.getMechanId();
        String[] typeArray = types.split(",");
        List<Integer> typeList = Arrays.stream(typeArray)
                .map(s -> Integer.parseInt(s.trim())).collect(Collectors.toList());
        List<PharmacyChooseRes> pharmacyChooseResList = pharmacyChooseMapper.getPahrChooseListByMechanRes(mechanId);
        List<PharOneRuleFeeRes> res = null;
        if (CollectionUtil.isNotEmpty(pharmacyChooseResList)) {
            List<Integer> pharIdList = pharmacyChooseResList.stream().map(PharmacyChooseRes::getPharId).collect(Collectors.toList());
            res = this.getBaseMapper().getOneRuleList(typeList, pharId, pharIdList);
        } else {
            res = this.getBaseMapper().getOneRuleListRes(typeList, pharId);
        }
        return res;
    }

    @Override
    public List<PharTwoRuleFeeRes> getTwoRuleList(String types, Integer pharId) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        Integer mechanId = loginInfo.getMechanId();
        String[] typeArray = types.split(",");
        List<Integer> typeList = Arrays.stream(typeArray)
                .map(s -> Integer.parseInt(s.trim())).collect(Collectors.toList());
        List<PharmacyChooseRes> pharmacyChooseResList = pharmacyChooseMapper.getPahrChooseListByMechanRes(mechanId);
        List<PharTwoRuleFeeRes> res = null;
        if (CollectionUtil.isNotEmpty(pharmacyChooseResList)) {
            List<Integer> pharIdList = pharmacyChooseResList.stream().map(PharmacyChooseRes::getPharId).collect(Collectors.toList());
            res = this.getBaseMapper().getTwoRuleList(typeList, pharId, pharIdList);
        } else {
            res = this.getBaseMapper().getTwoRuleListRes(typeList, pharId);
        }
        return res;
    }

    @Override
    public PharRuleRes getPharmacyRuleRes(Integer pharId) {
        PharRuleRes res = new PharRuleRes();
        LambdaQueryWrapper<PharFryingOneRule> oneWrapper = new LambdaQueryWrapper<>();
        oneWrapper.eq(PharFryingOneRule::getPharId, pharId)
                .eq(PharFryingOneRule::getIsChecked, 1);
        List<PharFryingOneRule> pharFryingOneRules = pharFryingOneRuleService.getBaseMapper().selectList(oneWrapper);
        res.setPharFryingOneRuleList(pharFryingOneRules);
        LambdaQueryWrapper<PharFryingTwoRule> twoWrapper = new LambdaQueryWrapper<>();
        twoWrapper.eq(PharFryingTwoRule::getPharId, pharId)
                .eq(PharFryingTwoRule::getIsChecked, 1);
        List<PharFryingTwoRule> pharFryingTwoRules = pharFryingTwoRuleService.getBaseMapper().selectList(twoWrapper);
        res.setPharFryingTwoRuleList(pharFryingTwoRules);
        LambdaQueryWrapper<PharExpressRule> expWrapper = new LambdaQueryWrapper<>();
        expWrapper.eq(PharExpressRule::getPharId, pharId);
        PharExpressRule pharExpressRule = pharExpressRuleService.getOne(expWrapper);
        res.setPharExpressRule(pharExpressRule);
        return res;
    }

    private PharFryRecordRes convertData(PharFryingRule recordRes) {
        PharFryRecordRes newPharFryRecordRes = new PharFryRecordRes();
        newPharFryRecordRes.setFryFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getFryFee()), new BigDecimal(100), 2) + "元")
                .setFryDose(recordRes.getFryDose() + "剂")
                .setFryTotalFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getFryTotalFee()), new BigDecimal(100), 2) + "元")
                .setIsFryChecked(recordRes.getIsFryChecked() == 1 ? "已勾选" : "未勾选")
                .setAnointingFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getAnointingFee()), new BigDecimal(100), 2) + "元")
                .setAnointingDose(recordRes.getAnointingDose() + "剂")
                .setIsAnointingChecked(recordRes.getIsAnointingChecked() == 1 ? "已勾选" : "未勾选")
                .setAnointingTotalFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getAnointingTotalFee()), new BigDecimal(100), 2) + "元")
                .setDrugDose(recordRes.getDrugDose() + "剂")
                .setDrugFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getDrugFee()), new BigDecimal(100), 2) + "元")
                .setDrugTotalFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getDrugTotalFee()), new BigDecimal(100), 2) + "元")
                .setIsDrugChecked(recordRes.getIsDrugChecked() == 1 ? "已勾选" : "未勾选")
                .setWaterPillsDose(recordRes.getWaterPillsDose() + "斤")
                .setWaterPillsFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getWaterPillsFee()), new BigDecimal(100), 2) + "元")
                .setWaterPillsTotalFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getWaterPillsTotalFee()), new BigDecimal(100), 2) + "元")
                .setIsWaterPillsChecked(recordRes.getIsWaterPillsChecked() == 1 ? "已勾选" : "未勾选")
                .setSecretPillsDose(recordRes.getSecretPillsDose() + "斤")
                .setSecretPillsFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getSecretPillsFee()), new BigDecimal(100), 2) + "元")
                .setSecretPillsTotalFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getSecretPillsTotalFee()), new BigDecimal(100), 2) + "元")
                .setIsSecretPillsChecked(recordRes.getIsSecretPillsChecked() == 1 ? "已勾选" : "未勾选")
                .setPowderDose(recordRes.getPowderDose() + "斤")
                .setPowderFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getPowderFee()), new BigDecimal(100), 2) + "元")
                .setPowderTotalFee(BigDecimalUtils.divide(new BigDecimal(recordRes.getSecretPillsTotalFee()), new BigDecimal(100), 2) + "元")
                .setIsPowderChecked(recordRes.getIsPowderChecked() == 1 ? "已勾选" : "未勾选");
        return newPharFryRecordRes;
    }

    private void saveExpRecord(PharExpOneRule pharExpRuleRes, PharExpOneRule oldExpressRule, LoginInfo loginInfo) {
        PharExpOneRule convertPharExpRule = new PharExpOneRule();
        BeanUtils.copyProperties(pharExpRuleRes, convertPharExpRule);
        PharExpRecordRes newPharExpRecordRes = convertExpData(convertPharExpRule);
        if (ObjectUtil.isNull(oldExpressRule)) {
            oldExpressRule = new PharExpOneRule();
            oldExpressRule.setCityOutFee(0)
                    .setCity("深圳市")
                    .setProvince("广东省")
                    .setProvincialOutFee(0)
                    .setCityFee(0)
                    .setIsChecked(0)
                    .setDeliverWay(1);
        }
        BeanUtils.copyProperties(oldExpressRule, convertPharExpRule);
        PharExpRecordRes oldPharExpRecordRes = convertExpData(convertPharExpRule);
        String recordRes = com.dd.cloud.common.utils.BeanUtils.getChangedFields(oldPharExpRecordRes, newPharExpRecordRes);
        if (StringUtils.isNotBlank(recordRes)) {
            recordRes = recordRes.substring(0, recordRes.length() - 1);
            PharSetFeeRecord pharSetFeeRecord = new PharSetFeeRecord();
            pharSetFeeRecord.setPharId(loginInfo.getPharId())
                    .setType(1)
                    .setUpdateContent(recordRes)
                    .setUpdateName(loginInfo.getName())
                    .setUpdateDate(LocalDateTime.now());
            pharSetFeeRecordService.save(pharSetFeeRecord);
        }
    }

    private PharExpRecordRes convertExpData(PharExpOneRule convertPharExpRule) {
        PharExpRecordRes newPharExpRecordRes = new PharExpRecordRes();
        if (convertPharExpRule.getFee() == null) {
            newPharExpRecordRes.setFee("未填写");
        } else {
            newPharExpRecordRes.setFee(BigDecimalUtils.divide(new BigDecimal(convertPharExpRule.getFee()), new BigDecimal(100), 2) + "元");
        }
        newPharExpRecordRes.setProvince(convertPharExpRule.getProvince())
                .setCityFee(BigDecimalUtils.divide(new BigDecimal(convertPharExpRule.getCityFee()), new BigDecimal(100), 2) + "元")
                .setCityOutFee(BigDecimalUtils.divide(new BigDecimal(convertPharExpRule.getCityOutFee()), new BigDecimal(100), 2) + "元")
                .setProvincialOutFee(BigDecimalUtils.divide(new BigDecimal(convertPharExpRule.getProvincialOutFee()), new BigDecimal(100), 2) + "元")
                .setIsChecked(convertPharExpRule.getIsChecked() == 1 ? "已勾选" : "未勾选")
                .setDeliveryWay(convertPharExpRule.getDeliverWay() == 1 ? "快递邮寄" : "快递到付");
        return newPharExpRecordRes;
    }
}
